package com.cantor.common.util;

import com.cantor.common.serializer.ToBeSerializedData;
import com.google.gson.*;
import lombok.SneakyThrows;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * Gson序列化工具类
 */
@Deprecated
public class GsonUtil {

    private GsonUtil() {

    }

    // 序列化为byte[]
    public static <T> byte[] serialize(T obj) {
        try {
            return new GsonBuilder()
                    .excludeFieldsWithoutExposeAnnotation()
                    .registerTypeAdapter(Class.class,new GsonAdapterClassCodec())
                    .create()
                    .toJson(new ToBeSerializedData<T>(obj))
                    .getBytes(StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 反序列化为T
    public static <T> T deserialize(byte[] bytes, Class<T> clz) {
        try {
            return (T) new Gson()
                    .fromJson(new String(bytes, StandardCharsets.UTF_8), ToBeSerializedData.class)
                    .getTarget();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 需要实现 JsonSerializer，JsonDeserializer 序列化和反序列化接口
     * 泛型 Class<?> 是说要把 java 那个类型序列化反序列化
     * 该适配器用于解决Gson无法序列化Class类型的成员变量的问题
     */
    static class GsonAdapterClassCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>>{

        // 反序列化
        @SneakyThrows
        @Override
        public Class<?> deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            String clazz = jsonElement.getAsString();
            return Class.forName(clazz);
        }

        // 序列化
        @Override
        public JsonElement serialize(Class<?> aClass, Type type, JsonSerializationContext jsonSerializationContext) {
            // 将 Class 变为 json
            return new JsonPrimitive(aClass.getName());
        }
    }

}
